
/*
soundpool(以停用)

audioplayers
适合短音频的播放(可同时播放多个,体积小) 可替换soundpool
https://pub-web.flutter-io.cn/packages/audioplayers
audioplayers: ^6.1.0
import 'package:audioplayers/audioplayers.dart';

其他:
audio_session:用于管理音频会话（Audio Session）的插件，主要用于配置和控制应用的音频行为，确保音频播放符合预期，并与其他应用或系统音频和谐共存。它在 Flutter 音频生态中（如 just_audio、audioplayers等）扮演重要角色
https://pub-web.flutter-io.cn/packages/audio_session

just_audio:音频播放（流媒体、本地文件,体积小）,音乐播放器、播客、有声书
https://pub-web.flutter-io.cn/packages/just_audio

flutter_sound: 录音 + 基础播放（全功能音频处理,体积大）,语音录制、即时通讯、音频编辑

 */


import 'package:flutter/services.dart';
import 'package:soundpool/soundpool.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_string.dart';


abstract class XSoundUtils{


  //audioplayers 支持鸿蒙////////////////////////////////////////////////////////////////////
  /*
  多播放同时:
  final AudioPlayer bgmPlayer = AudioPlayer();
final AudioPlayer effectPlayer = AudioPlayer();
// 同时播放背景音乐和音效
await bgmPlayer.play(AssetSource('bgm.mp3'));
await effectPlayer.play(AssetSource('effect.wav'));
   */
  static AudioPlayer? _audioPlayer;
  static Map<String,AudioPlayer?>? _audioPlayerMap;

  /*
      在pubspec.yaml中注册本地声音文件路径
        assets:
          - assets/sounds/
      初始化assetFilePaths: "sounds/dices.m4a"
       */
  static initAudioPlayers(
      List<String> assetFilePaths,//'sound/audio.mp3' 在assets中的路径
          {
        int releaseMode=0, //0 stop, 1 loop, 2 release
      }
      ) async{

    _audioPlayerMap?.forEach((k,v){
      v?.dispose();
    });
    _audioPlayerMap?.clear();
    _audioPlayerMap??={};

    ReleaseMode mode;
    if(releaseMode==1){
      mode=ReleaseMode.loop;
    }else if(releaseMode==2){
      mode=ReleaseMode.release;
    }else{
      mode=ReleaseMode.stop;//保留,Set the release mode to keep the source after playback has completed.
    }
    //
    assetFilePaths.forEach((v){
      AudioPlayer ap = AudioPlayer();
      ap.setReleaseMode(mode);
      ap.setSource(AssetSource(v));
      _audioPlayerMap![v]=ap;
    });
  }

  static initAudioPlayer(
      String assetFilePath,//'sound/audio.mp3' //在assets中的路径
          {
        int releaseMode=0, //0 stop, 1 loop, 2 release
      }
      ) async{

    ReleaseMode mode;
    if(releaseMode==1){
      mode=ReleaseMode.loop;
    }else if(releaseMode==2){
      mode=ReleaseMode.release;
    }else{
      mode=ReleaseMode.stop;//保留,Set the release mode to keep the source after playback has completed.
    }

    await _audioPlayer?.dispose();
    _audioPlayer = AudioPlayer();
    _audioPlayer?.setReleaseMode(mode);
    _audioPlayer?.setSource(AssetSource(assetFilePath));
    _lastPlayFile=assetFilePath;

    // _audioPlayer?.onPlayerStateChanged.listen((state) {
    //   XLogUtils.printLog('----播放状态: $state'); // 应为 PlayerState.playing
    // });

    // await _audioPlayer?.setAudioContext(AudioContext(
    //   android: AudioContextAndroid(
    //     contentType: AndroidContentType.music,
    //     usageType: AndroidUsageType.media,
    //     audioFocus: AndroidAudioFocus.gain,
    //   ),
    // ));

  }

  static String? _lastPlayFile;
  static void palyByAudioPlayer(
      {
        String? url,//'https://example.com/audio.mp3'
        String? assetFilePath,//'sound/audio.mp3' //在assets中的路径
        String? deviceFilePath,//'/sdcard/Music/song.mp3'
        Uint8List? audioBytes,//final Uint8List bytes = await File('audio.mp3').readAsBytes();
      }
      ) async{

    /*
    控制
    player.pause();          // 暂停
player.resume();         // 继续
player.stop();           // 停止（重置进度）
player.seek(Duration(seconds: 30));  // 跳转到30秒
player.setVolume(0.5);   // 音量（0.0 ~ 1.0）
player.setPlaybackRate(1.5); // 倍速播放（0.5 ~ 2.0）
     */
    if(_audioPlayer==null){
      _audioPlayer = AudioPlayer();
      //Set the release mode to keep the source after playback has completed.
      await _audioPlayer?.setReleaseMode(ReleaseMode.stop);
    }

    if(!XStringUtils.isEmpty(assetFilePath)){

      XLogUtils.printLog('---assetFilePath=$assetFilePath');

      if(_audioPlayerMap!=null){
        AudioPlayer? mAudioPlayer=_audioPlayerMap![assetFilePath];
        if(mAudioPlayer!=null){
          XLogUtils.printLog('---mAudioPlayer');
          mAudioPlayer.resume();
          return;
        }
      }

      if(assetFilePath==_lastPlayFile){
        //play内调用了setSource(),ReleaseMode.stop,
        XLogUtils.printLog('---resume');
        _audioPlayer?.resume();
      }else{
        XLogUtils.printLog('---_lastPlayFile=$_lastPlayFile');
        _lastPlayFile=assetFilePath;
        _audioPlayer?.play(AssetSource(assetFilePath!));
      }
    }else if(!XStringUtils.isEmpty(url)){

      if(url==_lastPlayFile){
        //play内调用了setSource(),ReleaseMode.stop,
        _audioPlayer?.resume();
      }else{
        _lastPlayFile=url;
        _audioPlayer?.play(UrlSource(url!));
      }

    }else if(!XStringUtils.isEmpty(deviceFilePath)){

      if(deviceFilePath==_lastPlayFile){
        //play内调用了setSource(),ReleaseMode.stop,
        _audioPlayer?.resume();
      }else{
        _lastPlayFile=deviceFilePath;
        _audioPlayer?.play(DeviceFileSource(deviceFilePath!));
      }
    }else if(audioBytes!=null){
      _audioPlayer?.play(BytesSource(audioBytes));
    }

  }

  static void stopAudioPlayer(){
    _audioPlayer?.stop();
    _audioPlayerMap?.forEach((k,v){
      v?.stop();
    });

  }

  static void releaseAudioPlayer(){
    _lastPlayFile=null;
    _audioPlayer?.dispose();

    if(_audioPlayerMap!=null){
      _audioPlayerMap!.forEach((k,v){
        v?.dispose();
      });
    }
  }




  //Soundpool 有项目在用,此库已停更新,不支持鸿蒙////////////////////////////////////////////////////////////////////

  static Soundpool? _soundpool;
  static List<int?> soundIds=[];

  /*
      在pubspec.yaml中注册本地声音文件路径
        assets:
          - assets/sounds/

      初始化filePath: "assets/sounds/dices.m4a"
       */
  static init(
      List<String> soundFilePaths,
      {
        int soundType=4,
      }
      ) async{
    //Soundpool soundpool = Soundpool(streamType: StreamType.notification);

    //只能初始化一次,声音文件加载一次,不能重复
    if(_soundpool==null){
      soundIds.clear();

      StreamType streamType;
      if(soundType==0){
        streamType=StreamType.ring;
      }else if(soundType==1){
        streamType=StreamType.alarm;
      }else if(soundType==2){
        streamType=StreamType.music;
      }else{
        streamType=StreamType.notification;
      }

      _soundpool = Soundpool.fromOptions(options: SoundpoolOptions(
        streamType: streamType,
      ));


      for(String filePath in soundFilePaths){

        int? soundId = await rootBundle.load(filePath).then((ByteData soundData) {
          return _soundpool?.load(soundData);
        });

        //
        XLogUtils.printLog('---init soundId=$soundId');

        soundIds.add(soundId);
      }

    }

  }


  //
  static void release(){
    _soundpool?.dispose();
    _soundpool=null;
    soundIds.clear();
  }

  //
  static void play(int? soundId){
    if(soundId!=null){
      _soundpool?.play(soundId);
    }
  }


}
